const db=require('./database')
const constant=require('../constant')
const sha256=require('sha256')
const stringRandom=require('string-random')

module.exports={
    GetIdByUserName:async function(username){
        let res=await db.GetAByBInT('users',['id'],{'username':username})
        if(res.length==0){
            throw constant.ERR_NONEXISTENT_USER
        }
        if(res.length>1){
            throw constant.ERR_REPEATED_USERS
        }
        return res[0].id
    },
    GetUsernameById:async function(id){
        let res=await db.GetAByBInT('users',['username'],{'id':id})
        if(res.length==0){
            throw constant.ERR_NONEXISTENT_USER
        }
        if(res.length>1){
            throw constant.ERR_REPEATED_USERS
        }
        return res[0].username
    },
    GetPasswordById:async function(id){
        let res=await db.GetAByBInT('users',['password'],{'id':id})
        if(res.length==0){
            throw constant.ERR_NONEXISTENT_USER
        }
        if(res.length>1){
            throw constant.ERR_REPEATED_USERS
        }
        return res[0].password
    },
    CreateUser:async function(username,password){
        try{
            await this.GetIdByUserName(username)
            throw constant.ERR_EXISTENT_USERS
        }catch(error){
            if(error==constant.ERR_NONEXISTENT_USER){
                await db.InsertAInT('users',{'username':username,'password':password})
            }else{
                throw error
            }
        }
    },
    IsPasswordRight:async function(username,password){
        return await this.GetPasswordById(await this.GetIdByUserName(username))==password
    },
    Login:async function(username,password){
        if(await this.IsPasswordRight(username,password)){
            let token=sha256(username+new Number(Date.now()).toString()+stringRandom(128,{specials:true}));
            await db.InsertAInT('tokens',{'id':await this.GetIdByUserName(username),'token':token})
            return token
        }else{
            throw constant.ERR_WRONG_PASSWORD
        }
    },
    IsRightToken:async function(token,id){
        if(token==undefined||id==undefined)return false;
        return (await db.GetAByBInT('tokens',['token','id'],{'token':token,'id':id})).length==1
    },
    Logout:async function(token){
        await db.DeleteAInT('tokens',{'token':token})
    }
}